package cinvestav.adviseme.databasemodel;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import cinvestav.adviseme.datamodel.Comentario;
import cinvestav.adviseme.datamodel.Persona;
import cinvestav.adviseme.util.DBException;
import cinvestav.adviseme.util.DataBaseDictionary;


public class ComentarioDB extends DataBase implements IComentarioDB{
	
	public ComentarioDB() throws DBException {
        super();
    }
	
	public List<Comentario> getByFilter(Map<String, String[]> filtros) throws DBException {
		try {
            //Se inicializa la coneccion
            //Se obtiene una nueva conexion
            Connection c = this.getConnection();
            //Se realiza la consulta
            PreparedStatement ps = genPreparedStatementString(filtros, c);
            ps.toString();
            ResultSet res = this.ejecutarQuery(ps);
            //Procesamiento de resultados
            List<Comentario> comentarios = new LinkedList<Comentario>();
            //Por cada elemento en el resultSet, se genera una nueva linea y se
            //agrega a la lista
            while (res.next()) {
                //Los elementos del resultSet se obtienen a partir del nombre de la columna
                //O por su indice en la tabla
                Comentario comentario = new Comentario();
                comentario.setId(res.getInt("ide_com"));
                comentario.setComentario(res.getString("com_com"));
                comentario.setRanking(res.getInt("ran_com"));
                comentario.setFecha(res.getDate("fec_com").toString());
                Persona persona = new Persona();   
                persona.setId(res.getInt("ide_per"));
                persona.setNombrePersona(res.getString("nom_per"));
                persona.setApellidoPaterno(res.getString("app_per"));
                persona.setApellidoMaterno(res.getString("apm_per"));                                            
                persona.setFotografia(res.getString("fot_per"));
                comentario.setPersona(persona);
                comentarios.add(comentario);
            }            
            c.close();
            return comentarios;
        } catch (SQLException ex) {
            Logger.getLogger(ComentarioDB.class.getName()).log(Level.SEVERE, null, ex);
            throw new DBException("Error al ejecutar la consulta:\n" + ex.getMessage());
        } catch (DBException ex) {
            throw new DBException(ex);
        }
	}
	
    private PreparedStatement genPreparedStatementString(Map<String, String[]> filtros, Connection c) {

        //Se obtiene la consulta base
        //A esta cadena se le iran concatenando los filtros segun corresponda
        String statement = DataBaseDictionary.GET_BASE_COMENTARIOS;
        //SE obtiene el alias de la tabla a utilizar
        String alias = DataBaseDictionary.ALIAS_COMENTARIO;
        //Bandera que indica el primer filtro
        Boolean ini = Boolean.TRUE;
        int i=0;
        //Se recorre el mapa de filtros para generar el String de la consulta
        for (Map.Entry<String, String[]> entry : filtros.entrySet()) {
            //entry - Contiene la entrada del mapa una por una
            //Si NO es el primer elemento se agrega un AND a la consulla
        	if (i!=0){
            statement += " AND";

            //Se agrega el filtro definido por el mapa
            statement += " " + alias + "." + entry.getKey();
        	}else{
        		statement += " " + alias + "." + entry.getKey();
        	}
        	i++;        		
        }

        //Una vez generada la cadena, se llenaran los datos del PreparedStatement '?'
        try {
            //Se inicializa el PreparedStatement y se liga este a la coneccion
            PreparedStatement ps = c.prepareStatement(statement);
            //llevara el indice de los elementos del ps, debe iniciar en 1
            int cont = 1;
            //Se recorre nuevamente el mapa de filtros
            for (Map.Entry<String, String[]> entry : filtros.entrySet()) {
                String[] val = entry.getValue();
                //Dependiendo del tipo de filtro, se agregan los valores al ps
                if (val[1].compareTo(DataBaseDictionary.STRING_SIMPLE) == 0) {
                    //Si es de tipo 'String_SIMPLE' es decir la busqueda se realiza con '='
                    ps.setString(cont, val[0]);
                } else if (val[1].compareTo(DataBaseDictionary.STRING_JOKER) == 0) {
                    //En este caso la busqueda se realiza con LIKE y se agrega el
                    //comodin de busqueda '%' al final del valor a buscar
                    ps.setString(cont, val[0] + "%");
                } else if (val[1].compareTo(DataBaseDictionary.STRING_DOBLE_JOKER) == 0) {
                    //En este caso la busqueda se realiza con LIKE y se agrega el
                    //comodin de busqueda '%' al final y al inicio del valor a buscar
                    ps.setString(cont, "%" + val[0] + "%");
                } else if (val[1].compareTo(DataBaseDictionary.INTEGER_TYPE) == 0) {
                    //Cuando el valor es entero
                    ps.setInt(cont, Integer.parseInt(val[0]));
                }
                cont++;
            }
            return ps;
        } catch (SQLException ex) {
            Logger.getLogger(ComentarioDB.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    public void insert(Comentario comentario) throws DBException{
    	try {
			Connection c = this.getConnection();
			PreparedStatement ps = c.prepareStatement(DataBaseDictionary.INSERT_COMENTARIO);
			DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
			
			ps.setInt(1, comentario.getId());
			ps.setString(2, comentario.getComentario());
			ps.setInt(3, comentario.getRanking());			
			ps.setString(4, comentario.getFecha());
			ps.setInt(5,comentario.getPersona().getId());
			ps.setInt(6,comentario.getLugar().getId());
			this.ejecutarInstruccion(ps);
			
			c.close();			
		} catch (SQLException e) {
			// TODO: handle exception
			 Logger.getLogger(ComentarioDB.class.getName()).log(Level.SEVERE, null, e);
			 throw new DBException("Error al ejecutar la consulta:\n" + e.getMessage(), e);
		}
    	
    }

}
